package com.okamura.handler;

import com.okamura.domain.PostListInfo;
import com.okamura.service.IPostListInfoService;
import com.okamura.utils.ClientConstants;
import com.okamura.utils.SpringUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.StringUtil;
import org.apache.log4j.Logger;

import java.net.InetSocketAddress;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

public class WcsClientHandler extends SimpleChannelInboundHandler<String> {
    private static Logger logger= Logger.getLogger(WcsClientHandler.class);
    private final AtomicInteger currentState;
    private final Runnable disconnectCallback;
    private IPostListInfoService postListInfoService = (IPostListInfoService) SpringUtil.getBean("postListInfoServiceImpl");

    public WcsClientHandler(AtomicInteger currentState,Runnable disconnectCallback){
        this.currentState=currentState;
        this.disconnectCallback=disconnectCallback;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //服务器连接成功
        currentState.set(ClientConstants.CLIENT_STATUS_STARTED);
    }

    /**
     * 从服务端获取消息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        //解析获取到的消息(MSG_ID+"ACK")并更新[POST_LIST_INFO]数据表{15573ACK}
        logger.info(msg);
        if (!StringUtil.isNullOrEmpty(msg)){
            handleResponse(ctx,msg);
        }
        return;
    }

    private void handleResponse(ChannelHandlerContext ctx,String response){
        Long msgId = Long.valueOf(response.trim().substring(0, 5));
        PostListInfo postInfo = postListInfoService.getPostInfoById(msgId);
        postInfo.setPostSt("2");
        postInfo.setAckMsg(response);
        postListInfoService.updatePostInfo(postInfo);
    }
    /**
     *获取异常
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("异常原因:"+cause.getMessage());
    }

    /**
     * 只有连接成功后再断开才会触发，如果第一次都未通讯成功，则一直不会触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String serverUrl=getRemoteAddress(ctx);
        if (!StringUtil.isNullOrEmpty(serverUrl)){
            logger.info("[Merro-ClientHandler] Client handler inactive, remote address: "+serverUrl);
        }
    }

    /**
     * 只要尝试connect且没有通讯成功就会触发，断开连接也会触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        String serverUrl=getRemoteAddress(ctx);
        if (!StringUtil.isNullOrEmpty(serverUrl)){
            logger.warn("[Merro-ClientHandler] Client channel unregistered,remote address:"+serverUrl);
        }
        currentState.set(ClientConstants.CLIENT_STATUS_OFF);
        disconnectCallback.run();
    }

    /**
     * 获取IP与端口号
     * @param ctx
     * @return
     */
    private String getRemoteAddress(ChannelHandlerContext ctx) {
        if (ctx.channel().remoteAddress() == null) {
            return null;
        }
        InetSocketAddress inetAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        return inetAddress.getAddress().getHostAddress() + ":" + inetAddress.getPort();
    }

    public int getCurrentState() {
        return currentState.get();
    }

    public boolean hasStarted() {
        return getCurrentState() == ClientConstants.CLIENT_STATUS_STARTED;
    }
}
